AI-Powered Short-Form Video Generator with OpenAI, Flux, Kling, and ElevenLabs and upload to all social networks
工作流概述
这是一个包含51个节点的复杂工作流,主要用于自动化处理各种任务。
工作流源代码
{
"id": "KY0vB3hifSrA24k2",
"meta": {
"instanceId": "3378b0d68c3b7ebfc71b79896d94e1a044dec38e99a1160aed4e9c323910fbe2",
"templateId": "3121"
},
"name": "AI-Powered Short-Form Video Generator with OpenAI, Flux, Kling, and ElevenLabs and upload to all social networks",
"tags": [],
"nodes": [
{
"id": "e5095169-dc78-4d90-9662-04cfc82c38d9",
"name": "Get image",
"type": "n8n-nodes-base.httpRequest",
"position": [
1160,
480
],
"parameters": {
"url": "=https://api.piapi.ai/api/v1/task/{{ $json.data.task_id }}",
"options": {},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-API-Key",
"value": "={{ $('Set API Keys').item.json['PiAPI Key'] }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "f477250a-fc8e-407e-a632-cffc0e564596",
"name": "Generate Image",
"type": "n8n-nodes-base.httpRequest",
"position": [
880,
480
],
"parameters": {
"url": "https://api.piapi.ai/api/v1/task",
"body": "={
\"model\": \"Qubico/flux1-dev\",
\"task_type\": \"txt2img\",
\"input\": {
\"prompt\": \"{{ $('Generate Image Prompts').item.json.choices[0].message.content }} realistic and casual as if taken by an iphone camera by a TikTok influencer\",
\"negative_prompt\": \"taking a photo of a room, recording a video of a room, photos app, video recorder, illegible text, blurry text, low quality text, DSLR, unnatural\",
\"width\": 540,
\"height\": 960
}
}",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "raw",
"sendHeaders": true,
"rawContentType": "application/json",
"headerParameters": {
"parameters": [
{
"name": "X-API-Key",
"value": "={{ $('Set API Keys').item.json['PiAPI Key'] }}"
}
]
}
},
"retryOnFail": false,
"typeVersion": 4.2
},
{
"id": "622ce9f5-ad58-485b-a3c6-1265700b04da",
"name": "Image-to-Video",
"type": "n8n-nodes-base.httpRequest",
"position": [
520,
1000
],
"parameters": {
"url": "https://api.piapi.ai/api/v1/task",
"body": "={
\"model\": \"kling\",
\"task_type\": \"video_generation\",
\"input\": {
\"prompt\": \"{{ $json.data.input.prompt }}\",
\"negative_prompt\": \"blurry motion, distorted faces, unnatural lighting, over produced, bad quality\",
\"cfg_scale\": 0.5,
\"duration\": 5,
\"mode\": \"pro\",
\"image_url\": \"{{ $json.data.output.image_url }}\",
\"version\": \"1.6\",
\"camera_control\": {
\"type\": \"simple\",
\"config\": {
\"horizontal\": 0,
\"vertical\": 0,
\"pan\": 0,
\"tilt\": 0,
\"roll\": 0,
\"zoom\": 5
}
}
},
\"config\": {}
}",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "raw",
"sendHeaders": true,
"rawContentType": "application/json",
"headerParameters": {
"parameters": [
{
"name": "X-API-Key",
"value": "={{ $('Set API Keys').item.json['PiAPI Key'] }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "ed14eac3-1d63-481d-871c-a04c52977fc6",
"name": "Get Video",
"type": "n8n-nodes-base.httpRequest",
"position": [
780,
1000
],
"parameters": {
"url": "=https://api.piapi.ai/api/v1/task/{{ $json.data.task_id }}",
"options": {},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-API-Key",
"value": "={{ $('Set API Keys').item.json['PiAPI Key'] }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "8b68100c-8a5a-405c-825e-d9e8a898f235",
"name": "List Elements",
"type": "n8n-nodes-base.code",
"position": [
1400,
1040
],
"parameters": {
"jsCode": "return [
{
scene_titles: items.map(item => item.json.response.text),
video_urls: items.map(item => item.json.data.output.video_url),
input_tokens: $('Calculate Token Usage').first().json.total_prompt_tokens,
output_tokens: $('Calculate Token Usage').first().json.total_completion_tokens,
model: $('Generate Image Prompts').first().json.model
}
];"
},
"typeVersion": 2
},
{
"id": "f8780885-508e-4dc9-b146-f367297d7b68",
"name": "Wait 10min",
"type": "n8n-nodes-base.wait",
"position": [
660,
1000
],
"webhookId": "1f9d716f-6544-4e4e-94ec-408ac3ea6e82",
"parameters": {
"unit": "minutes",
"amount": 10
},
"typeVersion": 1.1
},
{
"id": "6290bc91-0eb9-4053-bd93-961cb9e917c0",
"name": "Wait 3min",
"type": "n8n-nodes-base.wait",
"position": [
1020,
480
],
"webhookId": "77cdee73-5e99-456a-b5e7-410b4d257669",
"parameters": {
"unit": "minutes",
"amount": 3
},
"typeVersion": 1.1
},
{
"id": "818a66ef-b9fa-4efc-85d1-b295300cbed8",
"name": "Wait 5min",
"type": "n8n-nodes-base.wait",
"position": [
1480,
400
],
"webhookId": "31d5b1a2-dbb5-4849-ae25-cb491539c16e",
"parameters": {
"unit": "minutes"
},
"typeVersion": 1.1
},
{
"id": "afd66320-dfe0-4872-a09d-d53fe08152ce",
"name": "Generate voice",
"type": "n8n-nodes-base.httpRequest",
"position": [
880,
1460
],
"parameters": {
"url": "https://api.elevenlabs.io/v1/text-to-speech/onwK4e9ZLuTAKqWW03F9",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "text",
"value": "={{ $json.choices[0].message.content }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "xi-api-key",
"value": "={{ $('Set API Keys').item.json['ElevenLabs API Key'] }}"
}
]
}
},
"retryOnFail": false,
"typeVersion": 4.2
},
{
"id": "916f19e1-7928-4141-a5c5-ca39bd22b0a0",
"name": "List Elements1",
"type": "n8n-nodes-base.code",
"position": [
1400,
1260
],
"parameters": {
"jsCode": "return [
{
sound_urls: items.map(item => $('Upload Voice Audio').first().json.webContentLink)
}
];"
},
"typeVersion": 2
},
{
"id": "b95fd80c-ec7f-4d50-99ae-f3f544b8a111",
"name": "Fail check",
"type": "n8n-nodes-base.if",
"position": [
920,
1000
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a920eb54-fc23-4b68-8f56-2eee907a5481",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.data.status }}",
"rightValue": "failed"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "7e3f5cda-1d49-4a59-956f-f639daf203e0",
"name": "Wait to retry",
"type": "n8n-nodes-base.wait",
"position": [
1060,
960
],
"webhookId": "3b0fae8f-4419-45cd-8380-8f72eca05ff8",
"parameters": {
"unit": "minutes"
},
"typeVersion": 1.1
},
{
"id": "48ec39c9-1802-4860-918d-9c660051f27b",
"name": "Generate Image Prompts",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
400,
560
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "o3-mini",
"cachedResultName": "O3-MINI"
},
"options": {},
"messages": {
"values": [
{
"content": "=You are an advanced, unhinged, hilariously entertaining prompt-generation AI specializing in expanding short POV image prompt ideas into detailed, hyper-realistic prompts optimized for Qubico/flux1-dev. Your task is to take a brief input tied to job seeking, job hunting, or resume building and morph it into a cinematic, immersive prompt locked in a first-person perspective, making the viewer feel they’re living the scene.
NEVER include quotation marks or emojis in your response—flux API will choke on them, and that’s a hard no.
The topic of this narrative is: {{ $('Load Google Sheet').item.json.idea }}
The short prompt idea to expand for this image generation is: {{ $json.response.text }}
ONLY GENERATE ONE PROMPT PER IDEA—NO COMBINING. In at least one scene, weave in this environment descriptor: {{ $('Load Google Sheet').first().json.environment_prompt }}, but go wild with unhinged, edgy, funny twists elsewhere (skip the cringe or cheesy garbage). Most job hunting happens on laptops or desktops, so prioritize those over phones. If a phone sneaks in, it’s only showing job-related content like email, LinkedIn, a resume, or a job posting—never a photo or video app.
Every prompt has two parts:
Foreground: Kick off with First person view POV GoPro shot of... and show the viewer’s hands, limbs, or feet locked in a job-related action.
Background: Start with In the background,... and paint the scenery, blending the environment descriptor when required, plus sensory zingers.
Top Rules:
NO quotation marks or emojis—EVER. This is life or death for flux.
Stick to first-person POV—the viewer’s in the driver’s seat, not watching from the sidelines.
Show a limb (hands, feet) doing something job-focused—typing, holding a resume, adjusting a tie.
Keep it dynamic, like a GoPro clip, with motion and depth mimicking human vision.
If tech’s involved (phone, computer), it’s displaying job-hunting gold—email, job boards, resumes—not random trash.
No off-topic actions like recording videos or snapping pics—job hunting only, fam.
Extra Vibes:
Full-body awareness: Drop hints of physical feels—cramping fingers, racing pulse, slumping shoulders.
Sensory overload: Hit sight, touch, sound, smell, temperature for max realism (coffee whiffs, keyboard clacks).
World grip: Limbs interact with the scene—tapping keys, handing over papers, stepping up.
Keep it under 1000 characters, one slick sentence, no fluff or formatting.
Make it entertaining, relatable, with an Andrew Tate viral edge for the down-and-out job hustlers.
Examples:
Input: Updating a LinkedIn profile after a long day
Environment_prompt: Tired, cluttered apartment, laptop glow
Output: First person view POV GoPro shot of my hands hammering a laptop, cheeto-dusted fingers aching from the grind, the screen flashing my LinkedIn profile with a fresh connection ping; in the background, a trashed apartment lit by the laptop’s ghostly glow, pizza boxes toppling, traffic humming outside, stale takeout stench hitting my nose as my back screams from the hustle.
Input: Handing over a resume at a job fair
Environment_prompt: Hopeful, busy convention hall, suits everywhere
Output: First person view POV GoPro shot of my hand thrusting out a crisp resume, fingers twitching with nerves as it brushes another palm; in the background, a buzzing convention hall packed with suits, coffee fumes and shoe polish in the air, chatter drowning my pounding heart as I lock eyes with the recruiter.
NO QUOTATION MARKS. NO EMOJIS. EVER."
}
]
},
"simplify": false
},
"typeVersion": 1.8
},
{
"id": "5c1b8dc8-4eb3-49fe-81c7-c811d73fac0d",
"name": "Calculate Token Usage",
"type": "n8n-nodes-base.code",
"position": [
700,
560
],
"parameters": {
"jsCode": "// Get all input items (the 5 LLM responses)
const items = $input.all();
// Calculate total prompt tokens and total completion tokens
const totalPromptTokens = items.reduce((sum, item) => sum + item.json.usage.prompt_tokens, 0);
const totalCompletionTokens = items.reduce((sum, item) => sum + item.json.usage.completion_tokens, 0);
// Create new items with original data plus the totals
const outputItems = items.map(item => ({
json: {
...item.json, // Spread the original item data
total_prompt_tokens: totalPromptTokens, // Add total prompt tokens
total_completion_tokens: totalCompletionTokens // Add total completion tokens
}
}));
// Return the modified items
return outputItems;"
},
"typeVersion": 2
},
{
"id": "efc3d0dd-70dc-4fba-b040-22c773ed5602",
"name": "Check for failures",
"type": "n8n-nodes-base.if",
"position": [
1300,
480
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "567d1fc9-0638-4a44-b5f5-30a9a6683794",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.data.status }}",
"rightValue": "failed"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "3161c993-5696-4419-9299-fde51719dfc7",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
380,
240
],
"parameters": {
"color": 5,
"width": 1260,
"height": 460,
"content": "## 2. 🖼️Generate images with Flux using [PiAPI](https://piapi.ai/?via=n8n)
### (total cost: $0.0948 approx. as of 3/9/25)
1. OpenAI is used to generate 5 Flux image prompts based on the 5 captions generated. Edit this node to see/edit the prompt instructions.
2. Next we use some custom javascript to total up how many tokens were used for each 5 generations so we can track our costs later.
3. Then we generate an image with Flux using the [PiAPI service](https://piapi.ai/?via=n8n), waiting to check for failures and retrying if there are any.
You can change the image model used by editing the Generate Image node API call.
Flux models available (as of 3/9/25):
- Qubico/flux1-dev ($0.015) - Currently set
- Qubico/flux1-schnell ($0.0015)
- Qubico/flux1-advanced ($0.02)
For full list of API settings, see the [Flux API Documentation](https://piapi.ai/docs/flux-api/text-to-image?via=n8n)
"
},
"typeVersion": 1
},
{
"id": "e5cdec7e-cb75-4200-a8e3-615621d20150",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
480,
720
],
"parameters": {
"color": 6,
"width": 1040,
"height": 500,
"content": "## 3. 🎬Generate videos with Kling using [PiAPI](https://piapi.ai/?via=n8n)
### (total cost: $2.30 approx. as of 3/9/25)
1. We use image-to-video with Kling using [PiAPI](https://piapi.ai/?via=n8n) to generate a video from each image.
2. Then we wait to check for failures, and repeat the generations the failed if there are any.
You can edit the video model used in the Image-to-Video node. For testing, I'd recommend switching from pro to std for lower quality and cheaper price.
Kling models available (as of 3/9/25):
- std (Standard) $0.26 per 5 second video
- pro (Professional) $0.46 per 5 second video - Currently set
For full list of API settings, see the [Kling API Documentation](https://piapi.ai/docs/kling-api/create-task?via=n8n)
"
},
"typeVersion": 1
},
{
"id": "8404a390-a402-4703-8cb5-4a54490dc7bd",
"name": "Generate Video Captions",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
-40,
1220
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "GPT-4O-MINI"
},
"options": {},
"messages": {
"values": [
{
"role": "system",
"content": "DO NOT include any quotation marks in your response. Do not put a quote at the beginning or the end of your response.
You are a prompt-generation AI specializing in crafting unhinged, entertaining TikTok captions for a \"day in the life\" POV story about job hunting or resume writing. Generate five concise, action-driven captions (5-10 words each) that follow a Problem > Action > Reward structure. The first caption should be a shocking or funny hook, and the last should conclude with a satisfying reward. Use emojis sparingly—only one per caption at most, and only when they add impact; skip them if they don’t enhance the message.
Guidelines:
Perspective: Always first-person POV, immersing the viewer in the story.
Tone: Channel Andrew Tate mixed with Charlie Sheen—cursing and sexual innuendos are fair game.
Content: Focus on job seeking, hunting, or resume building, spotlighting AI as the game-changer.
Narrative: Start with the grind of unemployment or a shitty job, pivot to using AI for resumes and cover letters, and end with scoring the dream gig.
Scenes: Highlight raw, emotional moments—skip the boring stuff.
Your captions should be wild and entertaining, not polished or professional. The first caption is the hook—make it shocking, hilarious, or ballsy, something Andrew Tate would growl. Use emojis sparingly—max one per caption, only if it hits harder with it.
Your response should be a list of 5 items separated by \"\n\" (for example: \"item1\nitem2\nitem3\nitem4\nitem5\")"
},
{
"content": "={{ $json.idea }}"
}
]
},
"simplify": false
},
"typeVersion": 1.8
},
{
"id": "f614c784-a3ee-4eb8-aee3-cc0ad3e87556",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
480,
1240
],
"parameters": {
"color": 4,
"width": 1040,
"height": 400,
"content": "## 4. 🔉Generate voice overs with [Eleven Labs](https://try.elevenlabs.io/n8n)
1. OpenAI API is used to generate a funny script that relates to the captions. Open this node to see/edit the prompt instructions.
2. Then we use the [Eleven Labs API](https://try.elevenlabs.io/n8n) to generate the voiceover and upload it to our Google Drive so it can be accessed in the next step.
To replace the voice, find the voice ID of the voice you want to use in [Eleven Labs](https://try.elevenlabs.io/n8n), then change the URL in the Generate Voice node to: https://api.elevenlabs.io/v1/text-to-speech/{voice ID here}
For full list of API settings, see the [Eleven Labs API Documentation](https://elevenlabs.io/docs/api-reference/text-to-speech/convert)
"
},
"typeVersion": 1
},
{
"id": "e59306c1-8efe-4d98-9391-10c68c17787b",
"name": "Match captions with videos",
"type": "n8n-nodes-base.merge",
"position": [
1240,
1040
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3
},
{
"id": "8da7e16e-691b-4335-bfc7-e196c36f982d",
"name": "Generate Script",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
520,
1460
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "GPT-4O-MINI"
},
"options": {},
"messages": {
"values": [
{
"role": "system",
"content": "=You are an unhinged and hilarious TikTok influencer who's like a mix of Andrew Tate and Charlie Sheen. The user is going to provide you with a topic, and then 5 different parts of a story. Your task is to narrate the story as this hilarious character, who isn't afraid to be edgy or curse or use sexual innuendos. However keep each of the 5 talking points brief, as you only have about 5 seconds to speak during each. The entire length of your narration should be around 15 seconds.
Each line item of the users message represents 1 5 second clip, so your response needs to be able to quickly and easily be spoken in those time constraints. Don't say extra things you don't need to. Just quickly tell the story, in order, and make it unhinged, funny, entertaining, and potentially controversially viral. Don't worry about offendeding anyone. Andrew Tate style it.
Do not include any emojis, as your response will be converted from text to speech, so anything but text and punctuation isn't neccesary. Also, don't make your jokes overly corny, speak in a witty, edgy, funny way, but no corny dad jokes or anything cringe."
},
{
"content": "={{ $('Generate Video Captions').item.json.choices[0].message.content }}"
}
]
},
"simplify": false
},
"executeOnce": true,
"typeVersion": 1.8
},
{
"id": "ad87317d-3ed0-4fdf-aea5-7b2fa60fb59f",
"name": "Upload Voice Audio",
"type": "n8n-nodes-base.googleDrive",
"position": [
1080,
1460
],
"parameters": {
"name": "={{ $('Load Google Sheet').item.json.id }}-voiceover.mp3",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "1w1EQ8xyth6w7AbX2wpDI3vInfYeRy8vH",
"cachedResultUrl": "https://drive.google.com/drive/folders/1w1EQ8xyth6w7AbX2wpDI3vInfYeRy8vH",
"cachedResultName": "Resume Studio"
}
},
"typeVersion": 3
},
{
"id": "eec529e9-2601-4f7b-b415-63d2ebba1574",
"name": "Set Access Permissions",
"type": "n8n-nodes-base.googleDrive",
"position": [
1260,
1460
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"options": {},
"operation": "share",
"permissionsUi": {
"permissionsValues": {
"role": "writer",
"type": "anyone",
"allowFileDiscovery": true
}
}
},
"typeVersion": 3
},
{
"id": "63e72d56-140e-47d8-9f72-b58c764deed9",
"name": "Pair Videos with Audio",
"type": "n8n-nodes-base.merge",
"position": [
1620,
1140
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3
},
{
"id": "60a80c6f-0385-48e6-9b71-c23a74cbc15c",
"name": "Render Final Video",
"type": "n8n-nodes-base.httpRequest",
"position": [
1800,
1140
],
"parameters": {
"url": "https://api.creatomate.com/v1/renders",
"body": "={
\"template_id\": \"{{ $('Set API Keys').item.json['Creatomate Template ID'] }}\",
\"modifications\": {
\"Video-1.source\": \"{{ $json.video_urls[0] }}\",
\"Video-2.source\": \"{{ $json.video_urls[1] }}\",
\"Video-3.source\": \"{{ $json.video_urls[2] }}\",
\"Video-4.source\": \"{{ $json.video_urls[3] }}\",
\"Video-5.source\": \"{{ $json.video_urls[4] }}\",
\"Audio-1.source\": \"{{ $json.sound_urls[0] }}\",
\"Text-1.text\": \"{{ $json.scene_titles[0] }}\",
\"Text-2.text\": \"{{ $json.scene_titles[1] }}\",
\"Text-3.text\": \"{{ $json.scene_titles[2] }}\",
\"Text-4.text\": \"{{ $json.scene_titles[3] }}\",
\"Text-5.text\": \"{{ $json.scene_titles[4] }}\"
}
}",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "raw",
"sendHeaders": true,
"rawContentType": "application/json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $('Set API Keys').item.json['Creatomate API Key'] }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"executeOnce": true,
"typeVersion": 4.2
},
{
"id": "89c0e958-7690-4f3d-af49-3e9776f2c979",
"name": "Notify me on Discord",
"type": "n8n-nodes-base.discord",
"position": [
2780,
1140
],
"webhookId": "1541bc50-06e4-48e8-8c76-23850ee4edf6",
"parameters": {
"content": "=A new Resume Studio POV video has been created: {{ $json.final_output }}",
"options": {},
"authentication": "webhook"
},
"typeVersion": 2
},
{
"id": "14a09794-5e02-4880-b33d-139a91726dda",
"name": "Once Per Day",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-600,
1220
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 7
}
]
}
},
"typeVersion": 1.2
},
{
"id": "4de1f1c7-52ad-4e00-ad22-b4c3c0f718d8",
"name": "Load Google Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
-180,
1220
],
"parameters": {
"options": {
"returnFirstMatch": true
},
"filtersUI": {
"values": [
{
"lookupValue": "for production",
"lookupColumn": "production"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1cjd8p_yx-M-3gWLEd5TargtoB35cW-3y66AOTNMQrrM/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1cjd8p_yx-M-3gWLEd5TargtoB35cW-3y66AOTNMQrrM",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1cjd8p_yx-M-3gWLEd5TargtoB35cW-3y66AOTNMQrrM/edit?usp=drivesdk",
"cachedResultName": "Sheet Template"
}
},
"typeVersion": 4.5,
"alwaysOutputData": true
},
{
"id": "e5c83690-1696-43aa-a0db-164ca128dd67",
"name": "Create List",
"type": "n8n-nodes-base.code",
"position": [
280,
1140
],
"parameters": {
"jsCode": "// Get the text directly from the OpenAI response
const text = $input.first().json.choices[0].message.content;
// Split the text on literal '\\n', trim, and filter empty lines
const lines = text.split('\\n').map(line => line.trim()).filter(line => line !== '');
// Create an array of items for n8n
const items = lines.map(line => ({
json: {
response: { text: line }
}
}));
// Return the array of items
return items;"
},
"typeVersion": 2
},
{
"id": "ed99df67-2068-4c8b-a6ba-e67d234f03c4",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1560,
920
],
"parameters": {
"color": 3,
"width": 1360,
"height": 380,
"content": "## 5. 📥Complete video with [Creatomate](https://creatomate.com/)
### (total cost: $0.38 approx. with the Essential plan credits | Free trial credits available)
1. First, the list of videos/captions is combined with the generated voice over into a single item containing all 3 elements.
2. Those are then passed over to the Creatomate Template ID you specified, replacing the template captions/video/audio with your generated ones.
3. When the video is finished rendering, it's then uploaded to Google Drive and the permissions set so it can be accessed with a link.
4. Then we update the original Google Sheet template with the information from our generation, including tokens to calculate cost, then mark this idea as completed.
5. Finally, we send a notification to via [webhook to the Discord server](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks) when the video is ready to be downloaded and used!
"
},
"typeVersion": 1
},
{
"id": "e7064a56-c500-4f9f-a54a-c4352c263b56",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-320,
280
],
"parameters": {
"width": 620,
"height": 420,
"content": "# 🤖 AI-Powered Short-Form Video Generator with OpenAI, Flux, Kling, and ElevenLabs
## 📃Before you get started, you'll need:
- [n8n installation](https://n8n.partnerlinks.io/n8nTTVideoGenTemplate) (tested on version 1.81.4)
- [OpenAI API Key](https://platform.openai.com/api-keys) (free trial credits available)
- [PiAPI](https://piapi.ai/?via=n8n) (free trial credits available)
- [Eleven Labs](https://try.elevenlabs.io/n8n) (free account)
- [Creatomate API Key](https://creatomate.com/) (free trial credits available)
- Google Sheets API enabled in [Google Cloud Console](https://console.cloud.google.com/apis/api/sheets.googleapis.com/overview)
- Google Drive API enabled in [Google Cloud Console](https://console.cloud.google.com/apis/api/drive.googleapis.com/overview)
- OAuth 2.0 Client ID and Client Secret from your [Google Cloud Console Credentials](https://console.cloud.google.com/apis/credentials)
"
},
"typeVersion": 1
},
{
"id": "4ddb7249-9785-4f51-b35c-b9a0c6a66e3b",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-480,
780
],
"parameters": {
"color": 7,
"width": 920,
"height": 700,
"content": "## 1. 🗨️Generate video captions from ideas in a Google Sheet
1. Setup your API keys for [PiAPI](https://piapi.ai/?via=n8n), [Eleven Labs](https://try.elevenlabs.io/n8n), and [Creatomate](https://creatomate.com/).
- Once logged in to your Creatomate account, create a new video template and click \"source code\" in the top right. [Paste this JSON code](https://pastebin.com/c7aMTeLK). This will be your example template for this workflow.
- In your Creatomate template, click the \"Use Template\" button in the top right and then click \"API Integration\" and you'll see your template_id. Set this value as your Creatomate Template ID in the Set API Keys node
2. The next node will load a Google Sheet, you can copy the [Google Sheet Template](https://docs.google.com/spreadsheets/d/1cjd8p_yx-M-3gWLEd5TargtoB35cW-3y66AOTNMQrrM/edit?usp=sharing), simply choose File > Make a copy. Then in the Google Sheets node, connect to your copied sheet template.
3. Next, we generate 5 captions for our video idea with OpenAI. You can edit this node to see the prompt and change it to your needs.
4. In the final two nodes, we use custom javascript code to turn the OpenAI response into a list. Then, it validates to make sure the list was formed correctly (incase of an OpenAI failure to follow instructions)
"
},
"typeVersion": 1
},
{
"id": "57ee2f8f-5371-4dab-b661-c58b25c7dd55",
"name": "Wait1",
"type": "n8n-nodes-base.wait",
"position": [
1920,
1140
],
"webhookId": "206d0cdf-b71f-44a7-909f-97df885c471a",
"parameters": {
"unit": "minutes",
"amount": 3
},
"typeVersion": 1.1
},
{
"id": "33781e51-ef30-437b-8499-94e39bfb38fa",
"name": "Get Final Video",
"type": "n8n-nodes-base.httpRequest",
"position": [
2040,
1140
],
"parameters": {
"url": "=https://api.creatomate.com/v1/renders/{{ $('Render Final Video').item.json.id }}",
"options": {},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $('Set API Keys').item.json['Creatomate API Key'] }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"executeOnce": true,
"typeVersion": 4.2
},
{
"id": "b0d0fe6f-39c2-4da6-9fcf-b0151ed2c351",
"name": "Upload Final Video",
"type": "n8n-nodes-base.googleDrive",
"position": [
2300,
1140
],
"parameters": {
"name": "=POV-{{ $('Render Final Video').item.json.id }}.mp4",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "1w1EQ8xyth6w7AbX2wpDI3vInfYeRy8vH",
"cachedResultUrl": "https://drive.google.com/drive/folders/1w1EQ8xyth6w7AbX2wpDI3vInfYeRy8vH",
"cachedResultName": "Resume Studio"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "2TbhWtnbRfSloGxX",
"name": "Google Drive account"
}
},
"typeVersion": 3
},
{
"id": "3893d1de-7464-48ad-91a3-14b867c2a516",
"name": "Get Raw File",
"type": "n8n-nodes-base.httpRequest",
"position": [
2160,
1140
],
"parameters": {
"url": "={{ $json.url }}",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"typeVersion": 4.2
},
{
"id": "74de5f28-f081-4ec5-a47e-681eb845f701",
"name": "Set Permissions",
"type": "n8n-nodes-base.googleDrive",
"position": [
2440,
1140
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"options": {},
"operation": "share",
"permissionsUi": {
"permissionsValues": {
"role": "writer",
"type": "anyone",
"allowFileDiscovery": true
}
}
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "2TbhWtnbRfSloGxX",
"name": "Google Drive account"
}
},
"typeVersion": 3
},
{
"id": "a2c07158-e949-4b5b-a92e-f4b021742831",
"name": "Update Google Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
2600,
1140
],
"parameters": {
"columns": {
"value": {
"id": "={{ $('Load Google Sheet').first().json.id }}",
"width": "={{ $('Get Raw File').item.json.width }}",
"height": "={{ $('Get Raw File').item.json.height }}",
"model1": "={{ $('Generate Video Captions').item.json.model }}",
"model2": "={{ $('Pair Videos with Audio').item.json.model }}",
"model3": "={{ $('Generate Script').item.json.model }}",
"duration": "={{ $('Get Raw File').item.json.duration }}",
"fluxCost": "0.075",
"frameRate": "={{ $('Get Raw File').item.json.frame_rate }}",
"klingCost": "2.3",
"production": "done",
"publishing": "for publishing",
"final_output": "={{ $('Upload Final Video').item.json.webContentLink }}",
"prompt1 input tokens": "={{ $('Generate Video Captions').item.json.usage.prompt_tokens }}",
"prompt2 input tokens": "={{ $('Pair Videos with Audio').item.json.input_tokens }}",
"prompt3 input tokens": "={{ $('Generate Script').item.json.usage.prompt_tokens }}",
"prompt1 output tokens": "={{ $('Generate Video Captions').item.json.usage.completion_tokens }}",
"prompt2 output tokens": "={{ $('Pair Videos with Audio').item.json.output_tokens }}",
"prompt3 output tokens": "={{ $('Generate Script').item.json.usage.completion_tokens }}"
},
"schema": [
{
"id": "id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "id",
"defaultMatch": true,
"canBeUsedToMatch": true
},
{
"id": "idea",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "idea",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "caption",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "caption",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "production",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "production",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "environment_prompt",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "environment_prompt",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "publishing",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "publishing",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "final_output",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "final_output",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "width",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "width",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "height",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "height",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "duration",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "duration",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "frameRate",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "frameRate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "model1",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "model1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "prompt1 input tokens",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "prompt1 input tokens",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "prompt1 output tokens",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "prompt1 output tokens",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "model1 cost",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "model1 cost",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "model2",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "model2",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "prompt2 input tokens",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "prompt2 input tokens",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "prompt2 output tokens",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "prompt2 output tokens",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "model2 cost",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "model2 cost",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "model3",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "model3",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "prompt3 input tokens",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "prompt3 input tokens",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "prompt3 output tokens",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "prompt3 output tokens",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "model3 cost",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "model3 cost",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "cmCost",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "cmCost",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "upgradeCmCost",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "upgradeCmCost",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "fluxCost",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "fluxCost",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "klingCost",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "klingCost",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "totalCost",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "totalCost",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "datePosted",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "datePosted",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1cjd8p_yx-M-3gWLEd5TargtoB35cW-3y66AOTNMQrrM/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1cjd8p_yx-M-3gWLEd5TargtoB35cW-3y66AOTNMQrrM",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1cjd8p_yx-M-3gWLEd5TargtoB35cW-3y66AOTNMQrrM/edit?usp=drivesdk",
"cachedResultName": "Sheet Template"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "3IOU2VjBnR4hGohx",
"name": "Google Sheets account"
}
},
"typeVersion": 4.5
},
{
"id": "62423325-f9da-4cdf-8864-c011fb4fa14f",
"name": "Set API Keys",
"type": "n8n-nodes-base.set",
"notes": "SET BEFORE STARTING",
"position": [
-380,
1220
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "35659353-d8e2-4677-876b-401b549605a0",
"name": "PiAPI Key",
"type": "string",
"value": ""
},
{
"id": "c4927dd6-c597-48fe-b7c1-bbffcf5ff02f",
"name": "ElevenLabs API Key",
"type": "string",
"value": ""
},
{
"id": "f5e90c05-dd24-4918-9005-4c87a4fb344d",
"name": "Creatomate API Key",
"type": "string",
"value": ""
},
{
"id": "d0ebba50-5a99-4090-adcb-d18aa0b21be2",
"name": "Creatomate Template ID",
"type": "string",
"value": ""
}
]
}
},
"notesInFlow": true,
"typeVersion": 3.4
},
{
"id": "4252d793-5f16-4d5e-bb78-9b155aef5d3e",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-440,
1160
],
"parameters": {
"color": 3,
"width": 220,
"height": 220,
"content": "## DO THIS FIRST
"
},
"typeVersion": 1
},
{
"id": "845d5b4a-8a3f-4d0d-afce-39aa4e349a7b",
"name": "Validate list formatting",
"type": "n8n-nodes-base.if",
"position": [
280,
1280
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "2681c0e9-aa45-4f0f-8933-6e6de324c7aa",
"operator": {
"type": "array",
"operation": "lengthGt",
"rightType": "number"
},
"leftValue": "={{$input.all()}}",
"rightValue": 1
}
]
}
},
"typeVersion": 2.2
},
{
"id": "98a3761e-544a-473c-aa7f-cc14390750d8",
"name": "Get Audio from Video",
"type": "@n8n/n8n-nodes-langchain.openAi",
"notes": "Extract the audio from video for generate the description",
"position": [
3820,
1360
],
"parameters": {
"options": {},
"resource": "audio",
"operation": "transcribe"
},
"credentials": {
"openAiApi": {
"id": "XJdxgMSXFgwReSsh",
"name": "n8n key"
}
},
"notesInFlow": true,
"retryOnFail": true,
"typeVersion": 1,
"waitBetweenTries": 5000
},
{
"id": "ec498643-1ef1-42e5-90ee-ec49d0e2b63b",
"name": "Generate Description for Videos in Tiktok and Instagram",
"type": "@n8n/n8n-nodes-langchain.openAi",
"notes": "Request to OpenAi for generate description with the audio extracted from the video",
"position": [
4060,
1360
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o",
"cachedResultName": "GPT-4O"
},
"options": {},
"messages": {
"values": [
{
"role": "system",
"content": "You are an expert assistant in creating engaging social media video titles."
},
{
"content": "=I'm going to upload a video to social media. Here are some examples of descriptions that have worked well on Instagram:
Follow and save for later. Discover InfluencersDe, the AI tool that automates TikTok creation and publishing to drive traffic to your website. Perfect for entrepreneurs and brands.
#digitalmarketing #ugc #tiktok #ai #influencersde #contentcreation
Discover the video marketing revolution with InfluencersDe!
.
.
.
#socialmedia #videomarketing #ai #tiktok #influencersde #growthhacking
Don't miss InfluencersDe, the tool that transforms your marketing strategy with just one click!
.
.
.
#ugc #ai #tiktok #digitalmarketing #influencersde #branding
Can you create another title for the Instagram post based on this recognized audio from the video?
Audio: {{ $('Get Audio from Video').item.json.text }}
IMPORTANT: Reply only with the description, don't add anything else."
}
]
}
},
"credentials": {
"openAiApi": {
"id": "XJdxgMSXFgwReSsh",
"name": "n8n key"
}
},
"notesInFlow": true,
"retryOnFail": true,
"typeVersion": 1.4,
"waitBetweenTries": 5000
},
{
"id": "2f9f753d-86f3-4489-9dd2-a691f2da80ba",
"name": "Upload Video and Description to Tiktok",
"type": "n8n-nodes-base.httpRequest",
"notes": "Generate in upload-post.com the token and add to the credentials in the header-> Authorization: Apikey (token here)",
"position": [
4880,
940
],
"parameters": {
"url": "https://api.upload-post.com/api/upload",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "title",
"value": "={{ $('Generate Description for Videos in Tiktok and Instagram').item.json.message.content.replaceAll(\"\\"\", \"\") }}"
},
{
"name": "platform[]",
"value": "tiktok"
},
{
"name": "video",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
},
{
"name": "user",
"value": "Add user generated in upload-post"
}
]
},
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "WNjAx7UqrEZ1JDrR",
"name": "VituManco"
}
},
"notesInFlow": true,
"typeVersion": 4.2
},
{
"id": "4f007ef7-3f0a-4b4d-8dca-96028f29dd0c",
"name": "Upload Video and Description to Instagram",
"type": "n8n-nodes-base.httpRequest",
"notes": "Generate in upload-post.com the token and add to the credentials in the header-> Authorization: Apikey (token here)",
"position": [
4880,
1140
],
"parameters": {
"url": "https://api.upload-post.com/api/upload",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "title",
"value": "={{ $('Generate Description for Videos in Tiktok and Instagram').item.json.message.content.replaceAll(\"\\"\", \"\") }}"
},
{
"name": "platform[]",
"value": "instagram"
},
{
"name": "video",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
},
{
"name": "user",
"value": "Add user generated in upload-post"
}
]
},
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "47dO31ED0WIaJkR6",
"name": "Header Auth account"
}
},
"notesInFlow": true,
"typeVersion": 4.2
},
{
"id": "3805750b-65c4-4f28-b811-967681eda0ff",
"name": "Upload Video and Description to Youtube",
"type": "n8n-nodes-base.httpRequest",
"notes": "Generate in upload-post.com the token and add to the credentials in the header-> Authorization: Apikey (token here)",
"position": [
4880,
1360
],
"parameters": {
"url": "https://api.upload-post.com/api/upload",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "title",
"value": "={{ $('Generate Description for Videos in Tiktok and Instagram').item.json.message.content.replaceAll(\"\\"\", \"\").substring(0, 70) }}
"
},
{
"name": "platform[]",
"value": "youtube"
},
{
"name": "video",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
},
{
"name": "user",
"value": "Add user generated in upload-post"
}
]
},
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "47dO31ED0WIaJkR6",
"name": "Header Auth account"
}
},
"notesInFlow": true,
"typeVersion": 4.2
},
{
"id": "754e3f54-87cd-4b50-947e-a9b20ce2d2ab",
"name": "Upload Video and Description to Facebook",
"type": "n8n-nodes-base.httpRequest",
"notes": "Generate in upload-post.com the token and add to the credentials in the header-> Authorization: Apikey (token here)",
"position": [
4880,
1600
],
"parameters": {
"url": "https://api.upload-post.com/api/upload",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "title",
"value": "={{ $('Generate Description for Videos in Tiktok and Instagram').item.json.message.content.replaceAll(\"\\"\", \"\") }}"
},
{
"name": "platform[]",
"value": "facebook"
},
{
"name": "video",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
},
{
"name": "user",
"value": "Add user generated in upload-post"
},
{
"name": "facebook_page_id",
"value": "61556896550301"
}
]
},
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "47dO31ED0WIaJkR6",
"name": "Header Auth account"
}
},
"notesInFlow": true,
"typeVersion": 4.2
},
{
"id": "4090c098-2381-4e57-8e53-d24a2bed57cd",
"name": "Upload Video and Description to Linkedin",
"type": "n8n-nodes-base.httpRequest",
"notes": "Generate in upload-post.com the token and add to the credentials in the header-> Authorization: Apikey (token here)",
"position": [
4880,
1840
],
"parameters": {
"url": "https://api.upload-post.com/api/upload",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "title",
"value": "={{ $('Generate Description for Videos in Tiktok and Instagram').item.json.message.content.replaceAll(\"\\"\", \"\") }}"
},
{
"name": "platform[]",
"value": "linkedin"
},
{
"name": "video",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
},
{
"name": "user",
"value": "Add user generated in upload-post"
}
]
},
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "47dO31ED0WIaJkR6",
"name": "Header Auth account"
}
},
"notesInFlow": true,
"typeVersion": 4.2
},
{
"id": "cd9fbbf5-262e-43bc-9c09-382516de1cca",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
2940,
920
],
"parameters": {
"width": 2480,
"height": 1160,
"content": "## 6. Upload to all social networks with upload-post.com
### (premium plan 15$ | Free trial credits available)
This automation will automatically create descriptions from videos and upload it to Instagram, TikTok, Youtube, Facebook and Linkedin.
## How to Use
1. Generate an API token at upload-post.com and add to Upload to Tiktok and Upload to Instagram nodes etc
2. Customize the OpenAI prompt for your specific use case
3. Optional: Configure Telegram for error notifications
## Requirements
- upload-post.com account
- OpenAI API key
"
},
"typeVersion": 1
},
{
"id": "f3524df6-484b-40e6-a9a3-f4d2211f3988",
"name": "Read Video from Google Drive",
"type": "n8n-nodes-base.readBinaryFile",
"position": [
4420,
1360
],
"parameters": {
"filePath": "={{ $('Write video').item.json.originalFilename.replaceAll(\" \", \"_\") }}",
"dataPropertyName": "datavideo"
},
"typeVersion": 1
},
{
"id": "f082675c-1682-4679-88df-ae410e323f5b",
"name": "Write video",
"type": "n8n-nodes-base.writeBinaryFile",
"position": [
3440,
1360
],
"parameters": {
"options": {},
"fileName": "={{ $json.originalFilename.replaceAll(\" \", \"_\") }}"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "8f78312c-a5e3-48f0-a386-e1251586a6e7",
"connections": {
"Wait1": {
"main": [
[
{
"node": "Get Final Video",
"type": "main",
"index": 0
}
]
]
},
"Get Video": {
"main": [
[
{
"node": "Fail check",
"type": "main",
"index": 0
}
]
]
},
"Get image": {
"main": [
[
{
"node": "Check for failures",
"type": "main",
"index": 0
}
]
]
},
"Wait 3min": {
"main": [
[
{
"node": "Get image",
"type": "main",
"index": 0
}
]
]
},
"Wait 5min": {
"main": [
[
{
"node": "Generate Image",
"type": "main",
"index": 0
}
]
]
},
"Fail check": {
"main": [
[
{
"node": "Wait to retry",
"type": "main",
"index": 0
}
],
[
{
"node": "Match captions with videos",
"type": "main",
"index": 1
}
]
]
},
"Wait 10min": {
"main": [
[
{
"node": "Get Video",
"type": "main",
"index": 0
}
]
]
},
"Create List": {
"main": [
[
{
"node": "Validate list formatting",
"type": "main",
"index": 0
}
]
]
},
"Write video": {
"main": [
[
{
"node": "Get Audio from Video",
"type": "main",
"index": 0
}
]
]
},
"Get Raw File": {
"main": [
[
{
"node": "Upload Final Video",
"type": "main",
"index": 0
},
{
"node": "Write video",
"type": "main",
"index": 0
}
]
]
},
"Once Per Day": {
"main": [
[
{
"node": "Set API Keys",
"type": "main",
"index": 0
}
]
]
},
"Set API Keys": {
"main": [
[
{
"node": "Load Google Sheet",
"type": "main",
"index": 0
}
]
]
},
"List Elements": {
"main": [
[
{
"node": "Pair Videos with Audio",
"type": "main",
"index": 0
}
]
]
},
"Wait to retry": {
"main": [
[
{
"node": "Image-to-Video",
"type": "main",
"index": 0
}
]
]
},
"Generate Image": {
"main": [
[
{
"node": "Wait 3min",
"type": "main",
"index": 0
}
]
]
},
"Generate voice": {
"main": [
[
{
"node": "Upload Voice Audio",
"type": "main",
"index": 0
}
]
]
},
"Image-to-Video": {
"main": [
[
{
"node": "Wait 10min",
"type": "main",
"index": 0
}
]
]
},
"List Elements1": {
"main": [
[
{
"node": "Pair Videos with Audio",
"type": "main",
"index": 1
}
]
]
},
"Generate Script": {
"main": [
[
{
"node": "Generate voice",
"type": "main",
"index": 0
}
]
]
},
"Get Final Video": {
"main": [
[
{
"node": "Get Raw File",
"type": "main",
"index": 0
}
]
]
},
"Set Permissions": {
"main": [
[
{
"node": "Update Google Sheet",
"type": "main",
"index": 0
}
]
]
},
"Load Google Sheet": {
"main": [
[
{
"node": "Generate Video Captions",
"type": "main",
"index": 0
}
]
]
},
"Check for failures": {
"main": [
[
{
"node": "Wait 5min",
"type": "main",
"index": 0
}
],
[
{
"node": "Image-to-Video",
"type": "main",
"index": 0
}
]
]
},
"Render Final Video": {
"main": [
[
{
"node": "Wait1",
"type": "main",
"index": 0
}
]
]
},
"Upload Final Video": {
"main": [
[
{
"node": "Set Permissions",
"type": "main",
"index": 0
}
]
]
},
"Upload Voice Audio": {
"main": [
[
{
"node": "Set Access Permissions",
"type": "main",
"index": 0
}
]
]
},
"Update Google Sheet": {
"main": [
[
{
"node": "Notify me on Discord",
"type": "main",
"index": 0
}
]
]
},
"Get Audio from Video": {
"main": [
[
{
"node": "Generate Description for Videos in Tiktok and Instagram",
"type": "main",
"index": 0
}
]
]
},
"Notify me on Discord": {
"main": [
[]
]
},
"Calculate Token Usage": {
"main": [
[
{
"node": "Generate Image",
"type": "main",
"index": 0
}
]
]
},
"Generate Image Prompts": {
"main": [
[
{
"node": "Calculate Token Usage",
"type": "main",
"index": 0
}
]
]
},
"Pair Videos with Audio": {
"main": [
[
{
"node": "Render Final Video",
"type": "main",
"index": 0
}
]
]
},
"Set Access Permissions": {
"main": [
[
{
"node": "List Elements1",
"type": "main",
"index": 0
}
]
]
},
"Generate Video Captions": {
"main": [
[
{
"node": "Create List",
"type": "main",
"index": 0
}
]
]
},
"Validate list formatting": {
"main": [
[
{
"node": "Generate Image Prompts",
"type": "main",
"index": 0
},
{
"node": "Match captions with videos",
"type": "main",
"index": 0
},
{
"node": "Generate Script",
"type": "main",
"index": 0
}
],
[
{
"node": "Generate Video Captions",
"type": "main",
"index": 0
}
]
]
},
"Match captions with videos": {
"main": [
[
{
"node": "List Elements",
"type": "main",
"index": 0
}
]
]
},
"Read Video from Google Drive": {
"main": [
[
{
"node": "Upload Video and Description to Tiktok",
"type": "main",
"index": 0
},
{
"node": "Upload Video and Description to Instagram",
"type": "main",
"index": 0
},
{
"node": "Upload Video and Description to Youtube",
"type": "main",
"index": 0
},
{
"node": "Upload Video and Description to Facebook",
"type": "main",
"index": 0
},
{
"node": "Upload Video and Description to Linkedin",
"type": "main",
"index": 0
}
]
]
},
"Generate Description for Videos in Tiktok and Instagram": {
"main": [
[
{
"node": "Read Video from Google Drive",
"type": "main",
"index": 0
}
]
]
}
}
}
功能特点
- 自动检测新邮件
- AI智能内容分析
- 自定义分类规则
- 批量处理能力
- 详细的处理日志
技术分析
节点类型及作用
- Httprequest
- Code
- Wait
- If
- @N8N/N8N Nodes Langchain.Openai
复杂度评估
配置难度:
维护难度:
扩展性:
实施指南
前置条件
- 有效的Gmail账户
- n8n平台访问权限
- Google API凭证
- AI分类服务订阅
配置步骤
- 在n8n中导入工作流JSON文件
- 配置Gmail节点的认证信息
- 设置AI分类器的API密钥
- 自定义分类规则和标签映射
- 测试工作流执行
- 配置定时触发器(可选)
关键参数
| 参数名称 | 默认值 | 说明 |
|---|---|---|
| maxEmails | 50 | 单次处理的最大邮件数量 |
| confidenceThreshold | 0.8 | 分类置信度阈值 |
| autoLabel | true | 是否自动添加标签 |
最佳实践
优化建议
- 定期更新AI分类模型以提高准确性
- 根据邮件量调整处理批次大小
- 设置合理的分类置信度阈值
- 定期清理过期的分类规则
安全注意事项
- 妥善保管API密钥和认证信息
- 限制工作流的访问权限
- 定期审查处理日志
- 启用双因素认证保护Gmail账户
性能优化
- 使用增量处理减少重复工作
- 缓存频繁访问的数据
- 并行处理多个邮件分类任务
- 监控系统资源使用情况
故障排除
常见问题
邮件未被正确分类
检查AI分类器的置信度阈值设置,适当降低阈值或更新训练数据。
Gmail认证失败
确认Google API凭证有效且具有正确的权限范围,重新进行OAuth授权。
调试技巧
- 启用详细日志记录查看每个步骤的执行情况
- 使用测试邮件验证分类逻辑
- 检查网络连接和API服务状态
- 逐步执行工作流定位问题节点
错误处理
工作流包含以下错误处理机制:
- 网络超时自动重试(最多3次)
- API错误记录和告警
- 处理失败邮件的隔离机制
- 异常情况下的回滚操作